<?php declare(strict_types=1);
/**
 * This file is part of Swoft.
 *
 * @link     https://swoft.org
 * @document https://swoft.org/docs
 * @contact  group@swoft.org
 * @license  https://github.com/swoft-cloud/swoft/blob/master/LICENSE
 */

namespace App\Http\Controller\Test;

use Swoft\Http\Message\Request;
use Swoft\Http\Server\Annotation\Mapping\Controller;
use Swoft\Http\Server\Annotation\Mapping\RequestMapping;
use Swoft\Limiter\Annotation\Mapping\RateLimiter;
use Swoft\Http\Server\Annotation\Mapping\RequestMethod;

/**
 * https://www.swoft.org/documents/v2/microservice/limit/  【服务限流】
 * https://symfony.com/doc/current/components/expression_language/syntax.html#component-expression-objects 【key】
 * https://www.zhihu.com/people/phpkai-yuan-she-qu/zvideos 【swoft 微服务】
 * https://www.zhihu.com/zvideo/1258448049141358592 【限流视频】
 *
 * Class SwoftLimiterController
 *
 * @since 2.0
 *
 * @Controller(prefix="/Limiter")
 */
class SwoftLimiterController
{
    /*
        标记方法，开启限流策略，详细参数如下
        name 缓存前缀
        rate 允许多大的请求访问，请求数/秒
        key 限流 key, 支持 symfony/expression-language 表达式，key 表达式内置 CLASS(类名) 和 METHOD(方法名称) 两个变量，方便开发者使用。
        max 最大的请求数
        default 初始化请求数
        fallback 降级函数，和 breaker 一样
     */
    /**
     * 一秒钟之内请求数大于一次，返回异常
     * @RequestMapping(route="request_limiter",method={RequestMethod::GET})
     * @RateLimiter(key="request.getUriPath()",max=1)
     *
     * @param Request $request
     *
     * @return array
     */
    public function requestLimiter(Request $request)
    {
        $uri = $request->getUriPath();
        return ['requestLimiter', $uri];
    }

    /**
     * @RequestMapping(route="request_limiter2",method={RequestMethod::GET})
     * @RateLimiter(rate=20, fallback="limiterFallback")
     *
     * @param Request $request
     *
     * @return array
     */
    public function requestLimiter2(Request $request)
    {
        $uri = $request->getUriPath();
        return ['requestLimiter2', $uri];
    }

    /**
     * @param Request $request
     *
     * @return array
     */
    public function limiterFallback(Request $request)
    {
        $uri = $request->getUriPath();
        return ['limiterFallback', $uri];
    }

    /**
     * @RequestMapping(route="param_limiter",method={RequestMethod::GET})
     * @RateLimiter(key="request.getUriPath()~':'~request.query('id')")
     *
     * @param Request $request
     *
     * @return array
     */
    public function paramLimiter(Request $request)
    {
        $id = $request->query('id');
        return ['paramLimiter', $id];
    }

}
